﻿Imports Microsoft.DirectX.Direct3D
Imports Microsoft.DirectX
Imports Commander_Wars.Spieletools
Public Enum Richtungen
    Oben
    Rechts
    Unten
    Links
End Enum
<Serializable()> Public MustInherit Class ObjektEinheit
    Implements ICloneable


#Region "Variablen"
    Enum Stufe
        Soldat
        Leutnant
        Offizier
        General
        Veteran
        KO
    End Enum
    Public TruppenStufe As Stufe = Stufe.Soldat
    Public Property EinheitenStufe() As Stufe
        Get
            Return TruppenStufe
        End Get
        Set(ByVal value As Stufe)
            If TruppenStufe <> Stufe.KO Then
                If value > 0 Then
                    If TruppenStufe < Stufe.Veteran Then
                        TruppenStufe += 1
                    End If
                Else
                    TruppenStufe = Stufe.Soldat
                End If
            End If
        End Set
    End Property
    Public Leben As Single
    Public Sub IncreaseLeben(ByVal PLusLeben As Single)
        Leben += PLusLeben
        If Leben > 100 Then Leben = 100
        If Leben < 0 Then Leben = 1
    End Sub
    Public Property KP() As Single
        Get
            Return Leben
        End Get
        Set(ByVal value As Single)
            Leben += value
            If Leben > 100 Then Leben = 100
            If Leben <= 0 Then Tod = True
        End Set
    End Property
    Public Function getKP() As Integer
        Dim I As Integer = Math.DivRem(CInt(Leben), 10, 0)
        If I < 0 Then
            Return 0
        End If
        If Leben - I * 10 > 0 Then
            I += 1
        End If
        Return I
    End Function
    Public Sub SetKP(ByVal KP As Integer)
        Leben = KP * 10
    End Sub
    <NonSerialized()> Public X, Y As Integer
    <NonSerialized()> Public Tod As Boolean = False
    <NonSerialized()> Public SpritMax As Integer
    ''' <summary>
    ''' Die BildID von Infanteristen
    ''' </summary>
    ''' <remarks></remarks>
    <NonSerialized()> Public Shared INFID As Integer = -1
    Public Sprit As Integer
    Public Property Treibstoff() As Integer
        Get
            If SpritMax < 0 Then
                Return -1
            Else
                Return Sprit
            End If
        End Get
        Set(ByVal value As Integer)
            If SpritMax < 0 Then Exit Property
            If value < 0 Then
                Sprit += value * GetTreibstoffMultiplikator()
            Else
                Sprit += value
            End If
            If Sprit < 0 Then Sprit = 0
            If Sprit > SpritMax Then Sprit = SpritMax
        End Set
    End Property
    <NonSerialized()> Public Treibeverbrauch As Integer
    Public ReadOnly Property Treibstoffverbrauch() As Integer
        Get
            Return Treibeverbrauch
        End Get
    End Property
    <NonSerialized()> Public MunitionMax As Integer
    Protected Muni As Integer
    Public Property Munition() As Integer
        Get
            Return Muni
        End Get
        Set(ByVal value As Integer)
            If MunitionMax < 0 Then Exit Property
            Muni += value
            If Muni < 0 Then Muni = 0
            If Muni > MunitionMax Then Muni = MunitionMax
        End Set
    End Property
    <NonSerialized()> Private Name As String
    Public Property Einheitenname() As String
        Get
            Return Name
        End Get
        Set(ByVal value As String)
            Name = value
        End Set
    End Property
    Private EinheitenIDD As String
    Public Property EinheitenID() As String
        Get
            Return EinheitenIDD
        End Get
        Set(ByVal value As String)
            EinheitenIDD = value
        End Set
    End Property
    Private Besitzer As Integer
    Public Property Spieler() As Integer
        Get
            Return Besitzer
        End Get
        Set(ByVal value As Integer)
            Besitzer = value
        End Set
    End Property
    <NonSerialized()> Private BildIDD As Integer
    Public Property BildID() As Integer
        Get
            Return BildIDD
        End Get
        Set(ByVal value As Integer)
            BildIDD = value
        End Set
    End Property
    <NonSerialized()> Private Frames As Integer
    Public Property Frame() As Integer
        Get
            Return Frames
        End Get
        Set(ByVal value As Integer)
            Frames += 1
            If Frames > 3 Then
                Frames = 0
            End If
        End Set
    End Property
    <NonSerialized()> Private Bewpunkte As Integer
    Public Property Bewegungspunkte() As Integer
        Get
            If Bewpunkte + Bewegungsbonus < 0 Then
                Return 0
            Else
                Return Bewpunkte + Bewegungsbonus
            End If
        End Get
        Set(ByVal value As Integer)
            Bewpunkte = value
        End Set
    End Property
    Private Bewegt As Boolean
    Public Property HatsichBewegt() As Boolean
        Get
            Return Bewegt
        End Get
        Set(ByVal value As Boolean)
            Bewegt = value
            If My.Settings.draw3D Then
                'wenn das sich verändert hat, dann aktuallisieren wir am besten gleichmal das 3D
                AnimationAktuallisieren()
            End If
        End Set
    End Property
    <NonSerialized()> Private Bewegungsarte As String
    Public Property Bewegungsart() As String
        Get
            Return Bewegungsarte
        End Get
        Set(ByVal value As String)
            Bewegungsarte = value
        End Set
    End Property
    <NonSerialized()> Public Sicht As Integer
    Public Function GetSicht(ByVal X1 As Integer, ByVal Y1 As Integer) As Integer
        Dim Rückgabe As Integer = Sicht
        If Objektverwalter.Spielfeld.Regeln.Wetter = ObjektSpielfeld.Wetterarten.Regen Then
            Select My.Settings.CommanderWarsGameMoodus
                Case CommanderWarsGameModi.AdvanceWarsDC, CommanderWarsGameModi.CommanderWars2
                    If Not GetSpieler.KOS(0).Wetterimmunität.Contains(ObjektSpielfeld.Wetterarten.Regen) Then
                        'Nicht nur Kriegsnebel Nee auch noch Standard Sicht = 1. Des nen i aufair
                        Rückgabe = 1
                    End If
            End Select
        End If
        If GetSpieler.KOS(0).IsInKOZone(X1, Y1) Then
            Rückgabe += Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Sichtbonus
        End If
        If Bewegungsart = MovementSorts.Fuß.tostring Or Bewegungsart = MovementSorts.Mech.tostring Then
            If Objektverwalter.Spielfeld.Landschaften(X1, Y1, Me.GetMap).getID = "BERG" Or Objektverwalter.Spielfeld.Landschaften(X1, Y1, Me.GetMap).getID = "FELSEN" Or Objektverwalter.Spielfeld.Landschaften(X1, Y1, Me.GetMap).getID = "GIPFEL" Then
                Rückgabe += 3
            End If
        End If
        Rückgabe += SichtBonus
        Return Rückgabe
    End Function
    Public Function GetSicht() As Integer
        Return GetSicht(X, Y)
    End Function
    <NonSerialized()> Public KannBesetzen As Boolean = False
    Private Besetzung As Boolean = False
    Public Property Besetzen() As Boolean
        Get
            Return Besetzung
        End Get
        Set(ByVal value As Boolean)
            Besetzung = value
        End Set
    End Property
    <NonSerialized()> Public KannTarnen As Boolean = False
    ''' <summary>
    ''' Gibt an ob die Einheit untergetaucht ist.
    ''' </summary>
    ''' <remarks></remarks>
    Private Tarnung As Boolean = False
    Public Function GetTarnung() As Boolean
        Return Tarnung
    End Function
    Public Ladung() As ObjektEinheit = {}
    ''' <summary>
    ''' Die Einheiten die diese Einheit aufnehmen kann
    ''' </summary>
    ''' <remarks></remarks>
    <NonSerialized()> Public GeladeneEinheitenIDs() As String = {}
    <NonSerialized()> Public EntladungsUntergrund() As String = {}
    <NonSerialized()> Public Waffen1 As String
    Public Property Waffe1() As String
        Get
            If Waffen1.StartsWith("Material") Then Return "Keine"
            Return Waffen1
        End Get
        Set(ByVal value As String)
            Waffen1 = value
        End Set
    End Property
    <NonSerialized()> Public Waffen2 As String
    Public Property Waffe2() As String
        Get
            If Waffen2.StartsWith("Material") Then Return "Keine"
            Return Waffen2
        End Get
        Set(ByVal value As String)
            Waffen2 = value
        End Set
    End Property
    <NonSerialized()> Dim Sichtbarkeit As Boolean = True
    Property Sichtbar() As Boolean
        Get
            Return Sichtbarkeit
        End Get
        Set(ByVal value As Boolean)
            Sichtbarkeit = value
        End Set
    End Property
    <NonSerialized()> Protected Reichweitemin As Integer
    Public Property MinimaleReichweite() As Integer
        Get
            If My.Settings.CommanderWarsGameMoodus <> CommanderWarsGameModi.FireEmblem Then
                Return Reichweitemin
            Else
                Dim Min As Integer = -1
                Dim E As Fire_Emblem_MOD.FEUnit = Me
                For I = 0 To E.Items.Length - 1
                    If E.Items(I).CanUse(E) Then
                        If E.Items(I).MinRange > 0 Then
                            If E.Items(I).MinRange < Min Or Min <= 0 Then
                                Min = E.Items(I).MinRange
                            End If
                        End If
                    End If
                Next
                Return Min
            End If
        End Get
        Set(ByVal value As Integer)
            Reichweitemin = value
        End Set
    End Property
    <NonSerialized()> Public Reichweitemax As Integer
    ''' <summary>
    ''' Das Leben der Einheit in der KI-Berechnung.
    ''' </summary>
    ''' <remarks></remarks>
    <NonSerialized()> Public VirtuellesLeben As Single = 0
    <NonSerialized()> Public VirtuellerMeistSchaden As Integer = 0
    Public Property MaximaleReichweite() As Integer
        Get
            If My.Settings.CommanderWarsGameMoodus <> CommanderWarsGameModi.FireEmblem Then
                If EinheitenID <> "BOMBER" And EinheitenID <> "ZEPPELIN" Then
                    If Not Waffe2 = "Keine" Then
                        If Reichweitemax = 1 Then
                            Dim S As ObjektSpieler = GetSpieler()
                            If Not S Is Nothing Then
                                If S.KOS(0).IsInKOZone(Me) Then
                                    Return Reichweitemax + GetSpieler.KOS(0).NahkampfReichweitenBonus
                                Else
                                    Return Reichweitemax
                                End If
                            Else
                                Return Reichweitemax
                            End If
                        Else
                            Dim RMax As Integer = Reichweitemax + ReichweitenBonus
                            If Not Objektverwalter.Spielfeld Is Nothing Then
                                Dim S As Integer = Spieler
                                If S < 0 Then S = Objektverwalter.Spielfeld.AktuellerSpieler.Spieler
                                If Objektverwalter.Spielfeld.Spieler(S).KOS(0).IsInKOZone(X, Y) Then
                                    RMax += Objektverwalter.Spielfeld.Spieler(S).KOS(0).Reichweite
                                End If
                                Dim Stelle As Integer = Array.IndexOf(Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker, Objektverwalter.Spielfeld.Regeln.Wetter)
                                If Stelle >= 0 Then
                                    Select Case Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker(Stelle)
                                        Case ObjektSpielfeld.Wetterarten.Schnee
                                            If Bewegungsart.ToLower <> "wüstenketten" Then
                                                RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                                            End If
                                        Case ObjektSpielfeld.Wetterarten.Sandsturm
                                            If Bewegungsart.ToLower <> "schneeketten" Then
                                                RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                                            End If
                                        Case Else
                                            RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                                    End Select
                                End If

                            End If
                            If Reichweitemax < MinimaleReichweite Then
                                RMax = MinimaleReichweite
                            End If
                            'Haben wir Munition und eine Waffe 1?
                            If Munition <= 0 Then
                                If Waffe1 <> "Keine" Then
                                    RMax = 1
                                Else
                                    RMax = -1
                                End If
                            End If
                            'Noch ein paar andere Veränderungen wenn wir die Aktuelle Einheit steuern
                            If Objektverwalter.Spielfeld IsNot Nothing Then
                                If Objektverwalter.Spielfeld.AktuelleEinheit IsNot Nothing Then
                                    If Me.Equals(Objektverwalter.Spielfeld.AktuelleEinheit) Then
                                        If Objektverwalter.Spielfeld.Laufen IsNot Nothing Then
                                            If Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).MoveandFire = False Then
                                                If Objektverwalter.Spielfeld.AktuelleEinheit.Fähigkeit <> "MoveAndFire" Then
                                                    If Objektverwalter.Spielfeld.Laufen.Position <> Objektverwalter.Spielfeld.AktuelleEinheitPosition Then
                                                        If MinimaleReichweite = 1 Then
                                                            Select Case My.Settings.CommanderWarsGameMoodus
                                                                Case CommanderWarsGameModi.AdvanceWarsDC
                                                                    RMax = -1
                                                                Case Else
                                                                    RMax = 1
                                                            End Select
                                                        ElseIf Waffe1 <> "Keine" Then
                                                            RMax = 1
                                                        Else
                                                            RMax = -1
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                            Return RMax
                        End If
                    ElseIf Waffe1 <> "Keine" Then
                        If Objektverwalter.Spielfeld IsNot Nothing Then
                            Dim S As ObjektSpieler = GetSpieler()
                            If Not S Is Nothing Then
                                If S.KOS(0).IsInKOZone(Me) Then
                                    Return 1 + GetSpieler.KOS(0).NahkampfReichweitenBonus
                                Else
                                    Return 1
                                End If
                            Else
                                Return 1
                            End If
                        Else
                            Return 1
                        End If
                    Else
                        Return -1
                    End If
                Else
                    'Bomben fallen nunmal auf den Boden und nichts anderes!
                    Return Reichweitemax
                End If
            Else
                Dim Max As Integer = -1
                Dim E As Fire_Emblem_MOD.FEUnit = Me
                For I = 0 To E.Items.Length - 1
                    If E.Items(I).CanUse(E) Then
                        If E.Items(I).MaxRange > 0 Then
                            If E.Items(I).MaxRange > Max Then
                                Max = E.Items(I).MaxRange
                            End If
                        End If
                    End If
                Next
                Return Max
            End If
        End Get
        Set(ByVal value As Integer)
            Reichweitemax = value
        End Set
    End Property
    Private Fähigkeite As String = ""
    Public Property Fähigkeit() As String
        Get
            Return Fähigkeite
        End Get
        Set(ByVal value As String)
            Fähigkeite = value
        End Set
    End Property
    Public Koste As Integer
    Public ReadOnly Property Kosten() As Integer
        Get
            If Objektverwalter.Spielfeld IsNot Nothing Then
                Dim Verteuerung As Integer = CountUnits() * Objektverwalter.Spielfeld.Regeln.Teurungsrate
                Return Koste + Verteuerung
            Else
                Return Koste
            End If
        End Get
    End Property
    Private Explosione As String
    Public Property Explosion() As String
        Get
            Return Explosione
        End Get
        Set(ByVal value As String)
            Explosione = value
        End Set
    End Property
    'ein paar sachen fürs 3D
    Public Rotation As Single = Math.PI / 2
    Public AnimPos As Double
    Public AnimPeriode As Double
    Public AnimSetName As String = "Wait"
    Public AnimSetNächsterName As String = "Wait"
    ''' <summary>
    ''' Die Anzahl Frames, die gewartet wird, bevor die Animation von vorne beginnt. -1 für keinen Neudurchgang.
    ''' </summary>
    ''' <remarks></remarks>
    Public AnimAuszeit As Integer = -1

    'Diese drei Werte können für einen Zug verändert werden
    ''' <summary>
    ''' X=ATK und Y =Def
    ''' </summary>
    ''' <remarks></remarks>
    Public ATKDEFBoost As Point = New Point(0, 0)
    Public KannReapariertWerden As Boolean = True
    Public Bewegungsbonus As Integer = 0
    Public RadioaktiveVerseuchung As Integer = 0
    Public Feldtarnung As Boolean = False
    Public BesetzungsBonus As Integer = 0
    Public ReichweitenBonus As Integer = 0
    Public SichtBonus As Integer = 0
    Public TreibstoffSenkung As Integer = 0
    Public Sub IncreaseRadioaktiveVerseuchung(ByVal Wert As Integer)
        RadioaktiveVerseuchung += Wert
        If RadioaktiveVerseuchung < 0 Then RadioaktiveVerseuchung = 0
    End Sub
    Public Sub ResetWerte()
        ATKDEFBoost = New Point(0, 0)
        KannReapariertWerden = True
        Bewegungsbonus = 0
        Feldtarnung = False
        BesetzungsBonus = 0
        ReichweitenBonus = 0
        SichtBonus = 0
        TreibstoffSenkung = 0
        For I = 1 To 2
            If RadioaktiveVerseuchung > 0 Then
                RadioaktiveVerseuchung -= 1
                Leben -= 5
            End If
        Next
        If Leben <= 0 Then Leben = 1
        If RadioaktiveVerseuchung < 0 Then RadioaktiveVerseuchung = 0
    End Sub
    Public Sub RestoreUnit(ByVal Einheit As ObjektEinheit)
        'Noch ein paar andere Sachen laden.
        ATKDEFBoost = Einheit.ATKDEFBoost
        KannReapariertWerden = Einheit.KannReapariertWerden
        Bewegungsbonus = Einheit.Bewegungsbonus
        RadioaktiveVerseuchung = Einheit.RadioaktiveVerseuchung
        Feldtarnung = Einheit.Feldtarnung
        TruppenStufe = Einheit.TruppenStufe
        Rotation = Einheit.Rotation
        AnimPos = Einheit.AnimPos
        AnimPeriode = Einheit.AnimPeriode
        If Einheit.AnimSetName IsNot Nothing Then
            AnimSetName = Einheit.AnimSetName
        End If
        If Einheit.AnimSetNächsterName IsNot Nothing Then
            AnimSetNächsterName = Einheit.AnimSetNächsterName
        End If
        AnimAuszeit = Einheit.AnimAuszeit
    End Sub

#Region "Enumerrattion"



#End Region
#End Region
#Region "Einheit erschaffen"
    Public Sub New(ByVal neuSpieler As Integer, ByVal neuX As Integer, ByVal neuY As Integer, Optional ByVal Hatsichbewegt As Boolean = True)
        Spieler = neuSpieler
        DatenLaden()
        X = neuX
        Y = neuY
        Frames = Zufallszahl(0, 3)
        KP = 100
        Bewegt = Hatsichbewegt
    End Sub
    Public Sub New(ByVal neuKP As Integer, ByVal neuTreibstoff As Integer, ByVal neuMunition As Integer, ByVal neuSpieler As Integer, ByVal neuX As Integer, ByVal neuY As Integer, ByVal neuBesetzen As Boolean, ByVal HatSichbeWegt As Boolean, ByVal Tarnung As Boolean)
        Spieler = neuSpieler
        DatenLaden()
        X = neuX
        Y = neuY
        Frames = Zufallszahl(0, 3)
        Leben = neuKP
        Muni = neuMunition
        Sprit = neuTreibstoff
        Besetzung = neuBesetzen
        Bewegt = HatSichbeWegt
        Me.Tarnung = Tarnung
    End Sub
    Public Sub New(ByVal neuKP As Integer, ByVal neuSpieler As Integer, ByVal neuX As Integer, ByVal neuY As Integer, ByVal HatSichbeWegt As Boolean)
        Spieler = neuSpieler
        DatenLaden()
        X = neuX
        Y = neuY
        Frames = Zufallszahl(0, 3)
        Bewegt = HatSichbeWegt
        Leben = neuKP
    End Sub
    Public Sub BildIDbestimmen()
        For I = 0 To Objektverwalter.AlleEinheiten.Length - 1
            If Objektverwalter.AlleEinheiten(I).EinheitenID = EinheitenID Then
                BildID = I
                Exit For
            End If
        Next
    End Sub
    Protected MustOverride Sub DatenLaden()
#End Region
#Region "Funktionen"
    Public Sub setRotation(ByVal Richtung As richtungen)
        Rotation = Math.PI / 2 * Richtung
    End Sub
    Public Function getPosArt() As ObjektLandschaftsTextur.Positionsarten
        Return ObjektLandschaftsTextur.Positionsarten.Boden
    End Function
    Public Sub DoDamage(ByVal TP As Integer)
        Leben -= (TP * 10)
        If Leben <= 0 Then Leben = 1
        If Leben > 100 Then Leben = 100
    End Sub
    Public Function IsInFirerange(ByVal Einheit As ObjektEinheit) As Boolean
        Dim Distance As Integer = Math.Abs(X - Einheit.X) + Math.Abs(Einheit.Y - Y)
        If Distance >= MinimaleReichweite And Distance <= MaximaleReichweite Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Wir geben zurück ob die Einheit den Gegner angreifen könnte.
    ''' </summary>
    ''' <param name="Gegner"></param>
    ''' <param name="MitMuni"></param>
    ''' <param name="MitTarnung">wenn true, wird berücksichtigt, ob die Einheit den Gegner sieht</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsAttackable(ByVal Gegner As ObjektEinheit, ByVal MitMuni As Boolean, Optional ByVal MitTarnung As Boolean = True) As Boolean
        If Not Gegner Is Nothing Then

            If Objektverwalter.Spielfeld.Spieler(Gegner.Spieler).Team <> Objektverwalter.Spielfeld.Spieler(Spieler).Team Then
                If MitTarnung Then
                    If Not Gegner.isSichtbar(Me) Then Return False
                End If
                If Tabellenverwalter.GetWert(Waffe1, Gegner.EinheitenID) > 0 Then
                    Return True
                ElseIf MitMuni = True And Muni > 0 Then
                    If Tabellenverwalter.GetWert(Waffe2, Gegner.EinheitenID) > 0 Then
                        Return True
                    Else
                        Return False
                    End If
                ElseIf MitMuni = False And Tabellenverwalter.GetWert(Waffe2, Gegner.EinheitenID) > 0 Then
                    Return True
                Else
                    Return False
                End If

            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Wir geben zurück ob die Einheit den Gegner angreifen könnte.
    ''' </summary>
    ''' <param name="Gegner"></param>
    ''' <param name="MitMuni"></param>
    ''' <param name="MitTarnung"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetDamage(ByVal Gegner As ObjektEinheit, ByVal MitMuni As Boolean, Optional ByVal MitTarnung As Boolean = True) As Integer()
        If Not Gegner Is Nothing Then

            If Objektverwalter.Spielfeld.Spieler(Gegner.Spieler).Team <> Objektverwalter.Spielfeld.Spieler(Spieler).Team Then
                If MitTarnung Then
                    If Not Gegner.isSichtbar(Me) Then Return New Integer() {-1, -1}
                End If
                Dim W1 As Integer = Tabellenverwalter.GetWert(Waffe1, Gegner.EinheitenID)
                Dim W2 As Integer = -1
                If (MitMuni = True And Muni > 0) Or Not MitMuni Then
                    W2 = Tabellenverwalter.GetWert(Waffe2, Gegner.EinheitenID)
                End If
                If W1 >= 0 Or W2 >= 0 Then
                    If W1 >= W2 Then
                        Return New Integer() {W1, 1}
                    Else
                        Return New Integer() {W2, 2}
                    End If
                End If
            End If
        End If
        Return New Integer() {-1, -1}
    End Function
    ''' <summary>
    ''' Gibt zurück, ob die Einheit vom Aktuellen Spieler gesehen werden kann. Hierbei ist die KI mit dem Mensch gleichberechtigt :)
    ''' </summary>
    ''' <param name="Späher">Es wird überprüft, ob der Besitzer dieser Einheit, der aktuelle Spieler ist.</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function isSichtbar(ByVal Späher As ObjektEinheit) As Boolean
        Return isSichtbar(Objektverwalter.Spielfeld.Spieler(Späher.Spieler).Team)
    End Function
    Public Function isSichtbar(ByVal Team As Char) As Boolean
        If GetSpieler.Team = Team Then Return True
        If Team = Objektverwalter.Spielfeld.AktuellerSpieler.Team Then 'Ansonsten kann ich das leider nicht machen!
            If Me IsNot Nothing Then
                If Objektverwalter.Spielfeld.AktuellerSpieler.KIStufe = ObjektSpieler.KIStufen.Mensch Then
                    If Not Sichtbar Then
                        Return False
                    End If
                Else
                    If Objektverwalter.Spielfeld.KI IsNot Nothing Then
                        If Objektverwalter.Spielfeld.KI.Sichtfeld(X, Y) = False Then
                            Return False
                        End If
                    End If
                End If
            End If
        Else
            If DurchSichtfeldSichtbar(Team) Then
                Return True
            Else
                If ((IsGetarnt(Team) Or (Objektverwalter.Spielfeld.Landschaften(X, Y, GetMap).Tarnung And Objektverwalter.Spielfeld.Regeln.Nebel > Nebelarten.Aus And (Not IsFlyingUnit()))) And Not GetSpieler.KOS(0).RiffWaldSchauer) Then
                    Dim L As ObjektLandschaft
                    L = Wegsuchsystem.getFeldRundrum(X, Y, GetMap, 1, 1, Nothing, Objektverwalter.Spielfeld)
                    Do Until L Is Nothing
                        Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(L.KooX, L.KooY, GetMap)
                        If E IsNot Nothing Then
                            If E.GetSpieler.Team = Team Then
                                Return True
                            End If
                        End If
                        L = Wegsuchsystem.getFeldRundrum(X, Y, GetMap, 1, 1, L, Objektverwalter.Spielfeld)
                    Loop
                    Return False
                Else
                    If Objektverwalter.Spielfeld.Regeln.Nebel > Nebelarten.Aus Then
                        Dim Schlacht As Integer = GetMap()
                        For X1 = 0 To Objektverwalter.Spielfeld.Breite - 1
                            For Y1 = 0 To Objektverwalter.Spielfeld.Höhe - 1
                                Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X1, Y1, Schlacht)
                                If E IsNot Nothing Then
                                    If E.GetSpieler.Team = Team Then
                                        If E.GetDistance(Me) <= E.GetSicht Then
                                            Return True
                                        End If
                                    End If
                                End If
                                Dim L As ObjektLandschaft = Objektverwalter.Spielfeld.Landschaften(X1, Y1, Schlacht)
                                If L.LandschaftsID = "FEUER" Then
                                    If Me.GetDistance(New Point(X1, Y1)) <= LandschaftsTexturFeuer.FeuerSicht Then
                                        Return True
                                    End If
                                ElseIf L.Gebäude IsNot Nothing Then
                                    If L.Gebäude.Angriff = ObjektGebäude.Angriffe.Radar Then
                                        If Me.GetDistance(New Point(X1, Y1)) <= L.Gebäude.Reichweite Then
                                            Return True
                                        End If
                                    End If
                                End If
                            Next
                        Next
                        Return False
                    Else
                        Return True
                    End If
                End If
            End If
            Return False
        End If
        Return True
    End Function
    Public Function DurchSichtfeldSichtbar(ByVal Spieler As Integer) As Boolean
        Return DurchSichtfeldSichtbar(Objektverwalter.Spielfeld.Spieler(Spieler).Team)
    End Function
    Public Function DurchSichtfeldSichtbar(ByVal Team As Char) As Boolean
        For S = 1 To Objektverwalter.Spielfeld.Spieler.Length - 1
            If Objektverwalter.Spielfeld.Spieler(S).Team = Team Then
                For i = 0 To Objektverwalter.Spielfeld.Spieler(S).Sichtfelder.Length - 1
                    If Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Z = GetMap() Then
                        If GetDistance(New Point(Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).X, Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Y)) <= Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).W Then
                            Return True
                        End If
                    End If
                Next
            End If
        Next
        Return False
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit von dieser als Fracht aufgenommen werden kann.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsLoadable(ByVal Einheit As ObjektEinheit) As Boolean
        If Ladung.Length > 0 Then
            For I = 0 To GeladeneEinheitenIDs.Length - 1
                If GeladeneEinheitenIDs(I) = Einheit.EinheitenID Then
                    For Each E In Ladung
                        If E Is Nothing Then
                            Return True
                        End If
                    Next
                End If
            Next
            Return False
        Else
            Return False
        End If
        Return False
    End Function
    ''' <summary>
    ''' Überprüft ob von diesem Feld aus 
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsLoadingUnderground(ByVal X As Integer, ByVal Y As Integer) As Boolean
        Dim LandschaftsID As String = Objektverwalter.Spielfeld.Landschaften(X, Y, Me.GetMap).getID
        For Each ID In EntladungsUntergrund
            If ID = LandschaftsID Then
                Return True
            End If
        Next
        Return False
    End Function
    ''' <summary>
    ''' Gibt den Grundschaden zurück, welchen diese Einheit dem Gegner bei einem Angriff zufügen würde.
    ''' </summary>
    ''' <param name="Gegner"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetGroundDamage(ByVal Gegner As ObjektEinheit, ByVal MitMuni As Boolean) As Integer
        Dim S1 As Integer = Tabellenverwalter.GetWert(Waffe1, Gegner.EinheitenID)
        Dim S2 As Integer = Tabellenverwalter.GetWert(Waffe2, Gegner.EinheitenID)
        If MitMuni = True Then
            If Muni > 0 Then
                If S2 > S1 Then
                    Return S2
                Else
                    Return S1
                End If
            Else
                Return S1
            End If
        Else
            If S2 > S1 Then
                Return S2
            Else
                Return S1
            End If
        End If
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit über dieses Landschaft laufen kann.
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanMoveOverTile(ByVal X As Integer, ByVal Y As Integer, ByVal Schlacht As Integer) As Boolean
        If Objektverwalter.Spielfeld.OnMap(X, Y) = False Then Return False
        If Tabellenverwalter.GetWert(Bewegungsart + "+Sonne", Objektverwalter.Spielfeld.Landschaften(X, Y, Schlacht).getID) >= 0 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Gibt zurück ob die beiden Einheiten Gegner sind.
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsEnemy(ByVal Einheit As ObjektEinheit) As Boolean
        If Objektverwalter.Spielfeld.Spieler(Spieler).Team <> Objektverwalter.Spielfeld.Spieler(Einheit.Spieler).Team Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Berechnet die Bewegungspunkte der Einheit bei bestimmten Wetter bei -1 Wetter =Momentanes Wetter!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetMovementRange(Optional ByVal Wetter As ObjektSpielfeld.Wetterarten = -1) As Integer
        If Wetter < 0 Then Wetter = Objektverwalter.Spielfeld.Regeln.Wetter
        Dim TMultiplikator As Integer = GetTreibstoffMultiplikator(Wetter)
        Dim Bew As Integer = Bewegungspunkte
        Dim S As ObjektSpieler = GetSpieler()
        Dim K As ObjektKO = Nothing
        If S IsNot Nothing Then
            If S.KOS IsNot Nothing Then
                K = S.KOS(0)
            End If
        End If
        If K IsNot Nothing Then
            If GetSpieler.KOS(0).IsInKOZone(Me) Then
                If IsNothing(Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Bewegungsbonus) = False Then
                    Bew += Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Bewegungsbonus.GetWert(EinheitenID)
                End If
            End If
        End If
        If Wetter = ObjektSpielfeld.Wetterarten.Schnee Then
            Select Case My.Settings.CommanderWarsGameMoodus
                Case CommanderWarsGameModi.AdvanceWarsDC
                    If K IsNot Nothing Then
                        If Not GetSpieler.KOS(0).Wetterimmunität.Contains(ObjektSpielfeld.Wetterarten.Schnee) Then
                            'schnee nimmt uns in DC einen Bewegungspunkt weg.
                            'Idioten ich will nicht ich weigere mich
                            'Nützt nichts!
                            Bew -= 1
                            If Bew = 0 Then
                                Bew = 1
                            End If
                        End If
                    Else
                        Bew -= 1
                        If Bew = 0 Then
                            Bew = 1
                        End If
                    End If
                Case CommanderWarsGameModi.CommanderWars2
                    If Bewegungsart.ToLower <> "schneeketten" Then 'Schneepanzer sind Immun gegen Schnee!
                        If K IsNot Nothing Then
                            If Not GetSpieler.KOS(0).Wetterimmunität.Contains(ObjektSpielfeld.Wetterarten.Schnee) Then
                                'schnee nimmt uns in DC einen Bewegungspunkt weg.
                                'Idioten ich will nicht ich weigere mich
                                'Nützt nichts!
                                Bew -= 1
                                If Bew = 0 Then
                                    Bew = 1
                                End If
                            End If
                        Else
                            Bew -= 1
                            If Bew = 0 Then
                                Bew = 1
                            End If
                        End If
                    End If
            End Select
        End If
        If Bew * TMultiplikator > Treibstoff And Treibstoff >= 0 Then
            Bew = Math.DivRem(Treibstoff, TMultiplikator, 0)
        ElseIf Treibstoff < 0 Then
            Bew = Bew
        End If
        Return Bew
    End Function
    ''' <summary>
    ''' Soviel Treibstoff wird mehr verbraucht.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTreibstoffMultiplikator(Optional ByVal Wetter As ObjektSpielfeld.Wetterarten = -1) As Integer
        If Wetter < 0 Then Wetter = Objektverwalter.Spielfeld.Regeln.Wetter
        Dim TMultiplikator As Integer = 1
        Select Case My.Settings.CommanderWarsGameMoodus
            Case CommanderWarsGameModi.AdvanceWarsDS, CommanderWarsGameModi.CommanderWars2
                If Wetter = ObjektSpielfeld.Wetterarten.Schnee Then
                    If Bewegungsart.ToLower <> "schneeketten" Then
                        If GetSpieler.KOS(0).Wetterimmunität.Contains(ObjektSpielfeld.Wetterarten.Schnee) Then
                            TMultiplikator = 1
                        Else
                            TMultiplikator = 2
                        End If
                    Else
                        TMultiplikator = 1
                    End If
                Else
                    TMultiplikator = 1
                End If
            Case Else
                TMultiplikator = 1

        End Select
        Return TMultiplikator
    End Function
    ''' <summary>
    ''' Überprüft ob die Einheit andere Einheiten geladen hat.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function HasLadung() As Boolean
        For Each E In Ladung
            If Not E Is Nothing Then
                Return True
            End If
        Next
        Return False
    End Function
    Public Function IsLowPowerUnit(ByVal MinimalerTreibstoff As Single, ByVal MinimaleMunition As Single, ByVal MinimaleKP As Integer) As Boolean
        If MinimalerTreibstoff * SpritMax <= Treibstoff Then
            If MinimaleMunition * MunitionMax < Muni Or MunitionMax < 0 Or HasMaterial() Then
                If getKP() >= MinimaleKP Then
                    Return False
                End If
            End If

        End If
        Return True
    End Function
    ''' <summary>
    ''' Gibt zurück ob die KI die Einheit benutzt
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsUsingUnit(ByVal MinimalerTreibstoff As Single, ByVal MinimaleMunition As Single, ByVal MinimaleKP As Integer) As Boolean
        If HatsichBewegt = False Then
            If Leben > 0 Then
                If Treibstoff <> 0 Then
                    If MinimalerTreibstoff * SpritMax <= Treibstoff Then
                        If MinimaleMunition * MunitionMax <= Muni Or MinimaleMunition < 0 Then
                            If getKP() >= MinimaleKP Then
                                Dim S As ObjektSpieler = GetSpieler()
                                For I = 0 To S.ExternGezogeneEinheiten.Length - 1
                                    If Me.Equals(S.ExternGezogeneEinheiten(I).Einheit) Then
                                        Return False
                                    End If
                                Next
                                Return True
                            Else
                                Return False
                            End If
                        Else
                            Return False
                        End If
                    Else
                        'Eigentlich False aber für die Tests gerade True!
                        Return False
                    End If
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Gibt zurück ob diese Einheit Gebäude angreifen kann.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttackBuilding() As Boolean
        If Tabellenverwalter.GetWert(Waffe1, "Gebäude") > 0 Then
            Return True
        ElseIf Tabellenverwalter.GetWert(Waffe2, "Gebäude") > 0 And Munition > 0 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Tarnt die Einheit
    ''' </summary>
    ''' <param name="value"></param>
    ''' <remarks></remarks>
    Public Sub SetTarnung(ByVal value As Boolean)
        If KannTarnen = True Then
            Tarnung = value
        Else
            Tarnung = False
        End If
    End Sub
    ''' <summary>
    ''' Gibt zurück ob die Einheit für den Spieler getarnt ist
    ''' </summary>
    ''' <param name="Spieler"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsGetarnt(ByVal Spieler As Integer) As Boolean
        If Objektverwalter.Spielfeld.Spieler(Spieler).Team = GetSpieler.Team Then
            Return False
        Else
            If Tarnung = True Then
                Return True
            ElseIf Feldtarnung = True Then
                Return HatFeldTarnung(Spieler)
            Else
                Return False
            End If
        End If
    End Function
    Public Function IsGetarnt(ByVal Team As Char) As Boolean
        If Team = GetSpieler.Team Then
            Return False
        Else
            If Tarnung = True Then
                Return True
            ElseIf Feldtarnung = True Then
                Return HatFeldTarnung(Team)
            Else
                Return False
            End If
        End If
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit Feldtarnung hat oder nicht.
    ''' </summary>
    ''' <param name="Spieler"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function HatFeldTarnung(ByVal Spieler As Integer) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If X2 >= 0 And Y2 >= 0 And X2 < Objektverwalter.Spielfeld.Breite And Y2 < Objektverwalter.Spielfeld.Höhe Then
                If Not Objektverwalter.Spielfeld.Einheiten(X2, Y2, Me.GetMap) Is Nothing Then
                    If Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(X2, Y2, Me.GetMap).Spieler).Team = Objektverwalter.Spielfeld.Spieler(Spieler).Team Then
                        Return False
                    End If
                End If
            End If
        Next
        For S = 1 To Objektverwalter.Spielfeld.Spieler.Length - 1
            If Objektverwalter.Spielfeld.Spieler(S).Team = Objektverwalter.Spielfeld.Spieler(Spieler).Team Then
                For i = 0 To Objektverwalter.Spielfeld.Spieler(S).Sichtfelder.Length - 1
                    If Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Z = GetMap() Then
                        If GetDistance(New Point(Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).X, Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Y)) <= Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).W Then
                            Return False
                        End If
                    End If
                Next
            End If
        Next
        Return True
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit Feldtarnung hat oder nicht.
    ''' </summary>
    ''' <param name="Team"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function HatFeldTarnung(ByVal Team As Char) As Boolean
        Dim X2 As Integer = X
        Dim Y2 As Integer = Y
        For I = 0 To 3
            Select Case I
                Case 0
                    X2 -= 1
                Case 1
                    X2 += 1
                    Y2 -= 1
                Case 2
                    X2 += 1
                    Y2 += 1
                Case 3
                    X2 -= 1
                    Y2 += 1
            End Select
            If X2 >= 0 And Y2 >= 0 And X2 < Objektverwalter.Spielfeld.Breite And Y2 < Objektverwalter.Spielfeld.Höhe Then
                If Not Objektverwalter.Spielfeld.Einheiten(X2, Y2, Me.GetMap) Is Nothing Then
                    If Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Einheiten(X2, Y2, Me.GetMap).Spieler).Team Then
                        Return False
                    End If
                End If
            End If
        Next
        For S = 1 To Objektverwalter.Spielfeld.Spieler.Length - 1
            If Objektverwalter.Spielfeld.Spieler(S).Team = Team Then
                For i = 0 To Objektverwalter.Spielfeld.Spieler(S).Sichtfelder.Length - 1
                    If Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Z = GetMap() Then
                        If GetDistance(New Point(Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).X, Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).Y)) <= Objektverwalter.Spielfeld.Spieler(S).Sichtfelder(i).W Then
                            Return False
                        End If
                    End If
                Next
            End If
        Next
        Return True
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit untergetaucht ist.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsGetaucht() As Boolean
        Return Tarnung
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit für den Spieler getarnt ist
    ''' </summary>
    ''' <param name="Einheit"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsGetarnt(ByVal Einheit As ObjektEinheit) As Boolean
        Return IsGetarnt(Einheit.Spieler)
    End Function
    ''' <summary>
    ''' Legt die Feldtarnung der Einheit fest.
    ''' </summary>
    ''' <param name="value"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SetFeldtarnung(ByVal value As Boolean) As Boolean
        Feldtarnung = value
    End Function
    ''' <summary>
    ''' Gibt die Koordinaten der Einheit zurück.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetLocation() As Point
        Return New Point(X, Y)
    End Function
    ''' <summary>
    ''' Gibt das Terrain zurück auf dem diese Einheit steht
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetTerrain() As ObjektLandschaft
        If Not Objektverwalter.Spielfeld.Laufen Is Nothing Then
            If Me.Equals(Objektverwalter.Spielfeld.AktuelleEinheit) Then
                Return Objektverwalter.Spielfeld.Landschaften(Objektverwalter.Spielfeld.Laufen.Position.X, Objektverwalter.Spielfeld.Laufen.Position.Y, Me.GetMap)
            Else
                If Me.Equals(Objektverwalter.Spielfeld.Einheiten(X, Y, 0)) Then
                    Return Objektverwalter.Spielfeld.Landschaften(X, Y, 0)
                Else
                    Return Objektverwalter.Spielfeld.Landschaften(X, Y, 1)
                End If
            End If
        Else
            If Me.Equals(Objektverwalter.Spielfeld.Einheiten(X, Y, 0)) Then
                Return Objektverwalter.Spielfeld.Landschaften(X, Y, 0)
            Else
                Return Objektverwalter.Spielfeld.Landschaften(X, Y, 1)
            End If
        End If
    End Function
    Public Function GetTerrain(ByVal Schlacht As Integer) As ObjektLandschaft
        If Not Objektverwalter.Spielfeld.Laufen Is Nothing Then
            If Me.Equals(Objektverwalter.Spielfeld.AktuelleEinheit) Then
                Return Objektverwalter.Spielfeld.Landschaften(Objektverwalter.Spielfeld.Laufen.Position.X, Objektverwalter.Spielfeld.Laufen.Position.Y, Me.GetMap)
            Else
                Return Objektverwalter.Spielfeld.Landschaften(X, Y, Schlacht)
            End If
        Else
            Return Objektverwalter.Spielfeld.Landschaften(X, Y, Schlacht)
        End If
    End Function
    ''' <summary>
    ''' Gibt das Schlachfeld zurück auf dem die Einheit kämpft.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetMap() As Integer
        If Objektverwalter.Spielfeld.OnMap(X, Y) Then
            If Objektverwalter.Spielfeld.Laufen IsNot Nothing Then
                If Me.Equals(Objektverwalter.Spielfeld.AktuelleEinheit) Then
                    Return Objektverwalter.Spielfeld.MomentaneSchlacht
                Else
                    If Me.Equals(Objektverwalter.Spielfeld.Einheiten(X, Y, 0)) Then
                        Return 0
                    Else
                        Return 1
                    End If
                End If
            Else
                If X < 0 Or Y < 0 Then
                    Return Objektverwalter.Spielfeld.MomentaneSchlacht
                Else
                    If Me.Equals(Objektverwalter.Spielfeld.Einheiten(X, Y, 0)) Then
                        Return 0
                    Else
                        Return 1
                    End If
                End If
            End If
        Else
            Return Objektverwalter.Spielfeld.MomentaneSchlacht
        End If
    End Function
    ''' <summary>
    ''' Gibt das Schlachfeld zurück auf dem die Einheit kämpft.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetMap(ByVal Spielfeld As ObjektSpielfeld) As Integer
        If Not Spielfeld.Laufen Is Nothing Then
            If Me.Equals(Spielfeld.AktuelleEinheit) Then
                Return Spielfeld.MomentaneSchlacht
            Else
                If Me.Equals(Spielfeld.Einheiten(X, Y, 0)) Then
                    Return 0
                Else
                    Return 1
                End If
            End If
        Else
            If Me.Equals(Spielfeld.Einheiten(X, Y, 0)) Then
                Return 0
            Else
                Return 1
            End If
        End If
    End Function
    ''' <summary>
    ''' Gibt den Besitzer zurück.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSpieler() As ObjektSpieler
        If Spieler <= 0 Then
            If Objektverwalter.Spielfeld Is Nothing Then
                Return Nothing
            Else
                Return Objektverwalter.Spielfeld.Spieler(0)
            End If
        Else
            Return Objektverwalter.Spielfeld.Spieler(Spieler)
        End If
    End Function
    ''' <summary>
    ''' Gibt das Schlachtfeld zurück auf das die Einheit geschickt werden kann.
    ''' -1=Geht nicht
    ''' 0=Bodenschlacht
    ''' 1=Luftschlacht
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSendeMap() As Integer
        If Objektverwalter.Spielfeld.Regeln.Luftschlacht = True Then
            If Bewegungsart.ToUpper = MovementSorts.Flugzeug.ToString.ToUpper Then
                Dim Karte As Integer = GetMap()
                If Karte = ObjektSpielfeld.Bodenschlacht Then
                    Karte = ObjektSpielfeld.Luftschlacht
                Else
                    Karte = ObjektSpielfeld.Bodenschlacht
                End If
                If Objektverwalter.Spielfeld.AktuelleEinheit.Equals(Me) Then
                    If Objektverwalter.Spielfeld.Laufen Is Nothing Then
                        If Objektverwalter.Spielfeld.Einheiten(X, Y, Karte) Is Nothing Then
                            Return Karte
                        Else
                            Return -1
                        End If
                    Else
                        If Objektverwalter.Spielfeld.Einheiten(Objektverwalter.Spielfeld.Laufen.Position.X, Objektverwalter.Spielfeld.Laufen.Position.Y, Karte) Is Nothing Then
                            Return Karte
                        Else
                            Return -1
                        End If
                    End If
                Else
                    If Objektverwalter.Spielfeld.Einheiten(X, Y, Karte) Is Nothing Then
                        Return Karte
                    Else
                        Return -1
                    End If
                End If
            Else
                Return -1
            End If
        Else
            Return -1
        End If
    End Function
    ''' <summary>
    ''' Gibt die Waffe zurück, die bei einem Angriff benutzt bzw. benutzt werden würde.
    ''' </summary>
    ''' <param name="Opfer"></param>
    ''' <param name="Fernkampf"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetUsingWeapon(ByVal Opfer As ObjektEinheit, ByVal Fernkampf As Boolean) As Integer
        If Not Opfer Is Nothing Then
            Dim S1 As Single = Tabellenverwalter.GetWert(Waffe1, Opfer.EinheitenID)
            If Fernkampf = True Then S1 = -1
            Dim S2 As Single = -1
            If Muni > 0 Then
                S2 = Tabellenverwalter.GetWert(Waffe2, Opfer.EinheitenID)
            End If
            If S1 >= S2 Then
                Return 1
            Else
                Return 2
            End If
        End If
        Return -1
    End Function
    ''' <summary>
    ''' Gibt zurück ob die Einheit fliegt.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsFlyingUnit() As Boolean
        If Bewegungsart = MovementSorts.Flugzeug.tostring Or Bewegungsart = MovementSorts.Helikopter.tostring Then
            Return True
        ElseIf Explosione.ToLower = "luft" Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Function KannNurFernkampf() As Boolean
        If MinimaleReichweite > 1 And Waffe1 = "Keine" Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Function HasNoWeapons() As Boolean
        If Waffe1 = "Keine" And Waffe2 = "Keine" Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Berechnet aus Kosten und Leben den Wert der Einheit.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetEinheitenWert() As Integer
        Return (getKP() / 10) * Kosten * GetSpieler.Teurungsrate(Me, Me.X, Me.Y)
    End Function
    Public Function GetKampfanimation() As Objektverwalter.Kampfanimation
        Return Objektverwalter.AlleEinheiten(BildID).GetKampfAnimation(GetSpieler.Armee)
    End Function
    Public Function GetDistance(ByVal Opfer As ObjektEinheit) As Integer
        Dim X As Integer = Me.X
        Dim Y As Integer = Me.Y
        If Objektverwalter.Spielfeld.AktuelleEinheit IsNot Nothing Then
            If Opfer.Equals(Objektverwalter.Spielfeld.AktuelleEinheit) Then
                If Objektverwalter.Spielfeld.Laufen IsNot Nothing Then
                    Opfer.X = Objektverwalter.Spielfeld.Laufen.Position.X
                    Opfer.Y = Objektverwalter.Spielfeld.Laufen.Position.Y
                End If
            Else
                If Objektverwalter.Spielfeld.Laufen IsNot Nothing Then
                    X = Objektverwalter.Spielfeld.Laufen.Position.X
                    Y = Objektverwalter.Spielfeld.Laufen.Position.Y
                End If
            End If
        Else
            If Objektverwalter.Spielfeld.Laufen IsNot Nothing Then
                X = Objektverwalter.Spielfeld.Laufen.Position.X
                Y = Objektverwalter.Spielfeld.Laufen.Position.Y
            End If
        End If
        Return Math.Abs(X - Opfer.X) + Math.Abs(Y - Opfer.Y)
    End Function
    Public Function GetDistance(ByVal P As Point)
        Return Math.Abs(X - P.X) + Math.Abs(Y - P.Y)
    End Function
    ''' <summary>
    ''' Gibt zurück ob diese Einheit Bodentruppen angreifen kann.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttackGroundUnits() As Boolean
        If Tabellenverwalter.GetWert(Waffe1, "KPZ") > 0 Then
            Return True
        ElseIf Muni > 0 Then
            If Tabellenverwalter.GetWert(Waffe2, "KPZ") > 0 Then
                Return True
            Else
                Return False
            End If
        End If
    End Function
    ''' <summary>
    ''' Gibt zurück ob diese Einheit Seetruppen angreifen kann.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttackSeaUnits() As Boolean
        If Tabellenverwalter.GetWert(Waffe1, "KREUZER") > 0 Then
            Return True
        ElseIf Muni > 0 Then
            If Tabellenverwalter.GetWert(Waffe2, "KREUZER") > 0 Then
                Return True
            Else
                Return False
            End If
        End If
    End Function
    ''' <summary>
    ''' Gibt zurück ob diese Einheit Lufttruppen angreifen kann.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttackAirUnits() As Boolean
        If Tabellenverwalter.GetWert(Waffe1, "BOMBER") > 0 Then
            Return True
        ElseIf Muni > 0 Then
            If Tabellenverwalter.GetWert(Waffe2, "BOMBER") > 0 Then
                Return True
            Else
                Return False
            End If
        End If
    End Function
    Public Function HasPlaceforLoading() As Boolean
        For I = 0 To Ladung.Length - 1
            If Ladung(I) Is Nothing Then
                Return True
            End If
        Next
        Return False
    End Function
    Public Function IsFernwaffe() As Boolean
        If MaximaleReichweite > 1 Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Overridable Function GetCWMunition() As Integer
        Return MunitionMax
    End Function
    Public Function HasMaterial() As Boolean
        If Waffen2.StartsWith("Material") Then
            Return True
        ElseIf Waffen2.StartsWith("Material") Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        If MyBase.Equals(obj) Then
            Return True
        Else
            If TypeOf obj Is ObjektEinheit Then
                Dim E As ObjektEinheit = obj
                If Not E Is Nothing Then
                    If E.X = X Then
                        If E.Y = Y Then
                            If E.Munition = Munition Then
                                If E.Treibstoff = Treibstoff Then
                                    If E.Tarnung = Tarnung Then
                                        If E.TruppenStufe = TruppenStufe Then
                                            If E.Spieler = Spieler Then
                                                If E.RadioaktiveVerseuchung = RadioaktiveVerseuchung Then
                                                    If E.Leben = Leben Then
                                                        If E.KannReapariertWerden = KannReapariertWerden Then
                                                            If E.Frames = Frames Then
                                                                If E.EinheitenIDD = EinheitenIDD Then
                                                                    'So viele Zufälle kann es nicht geben! und wenn doch die Chance ist sehr gering!
                                                                    obj = Me
                                                                    Return True
                                                                End If
                                                            End If
                                                        End If
                                                    End If
                                                End If
                                            End If
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Überprüft ob eine Einheit angreifen kann, also ob sie eine Waffe hat.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttack() As Boolean
        If Waffe1 <> "Keine" Or Waffe2 <> "Keine" Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Ist es eine Seeeinheit?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsSeaUnit() As Boolean
        If Bewegungsart = MovementSorts.Transport.tostring Then
            Return True
        ElseIf Bewegungsart = MovementSorts.Schiff.tostring Then
            Return True
        ElseIf Explosion.ToLower = "wasser" Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Ist es eine Bodeneinheit
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsGroundUnit() As Boolean
        If Not IsSeaUnit() Then
            If Not IsFlyingUnit() Then
                Return True
            End If
        End If
        If Explosion.ToLower = "land" Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Wie groß die stärke gegen Luftwaffe ist von -1 bis viel!
    ''' Je größer desto besser
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetAntiAirDamage() As Integer
        Dim S1 As Single = Tabellenverwalter.GetWert(Waffe1, "BOMBER")
        Dim S2 As Single = Tabellenverwalter.GetWert(Waffe2, "BOMBER")
        If S1 >= S2 Then
            Return S1
        Else
            Return S2
        End If
    End Function
    ''' <summary>
    ''' Zählt wie viele Einheiten es von diesem Typ auf der Karte von Besitzer dieses Spielers gibt!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CountUnits() As Integer
        If Objektverwalter.Spielfeld Is Nothing Then Return 0
        Dim S As Integer = Spieler
        If S <= 0 Then S = Objektverwalter.Spielfeld.AktuellerSpieler.Spieler
        Dim Truppen As Integer
        For Each E In Objektverwalter.Spielfeld.Einheiten
            If Not E Is Nothing Then
                If E.Spieler = S Then
                    If E.EinheitenID = EinheitenID Then
                        Truppen += 1
                    End If
                End If
            End If
        Next
        Return Truppen
    End Function
    ''' <summary>
    ''' Ist diese Einheit ein Nahkämpfer!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function IsNahkampfEinheit() As Boolean
        If Not Waffe1.ToLower = "keine" Then
            Return True
        ElseIf MinimaleReichweite = 1 Then
            Return True
        Else
            Return False
        End If
    End Function
    ''' <summary>
    ''' Gibt die Spieler Farbe zurück!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetSpielerFarbe() As Color
        Return GetSpieler.Farbe
    End Function
    ''' <summary>
    ''' Wie viele Einheiten haben wir geladen?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetGeladeneEinheitenZahl() As Integer
        Dim T As Integer = 0
        For Each E In Ladung
            If E IsNot Nothing Then
                T += 1
            End If
        Next
        Return T
    End Function
    ''' <summary>
    ''' Schaut nur ob diese Einheit wenn sie sich bewegt Angreifen könnte. Aber nicht ob ein Opfer in der nähe ist
    ''' </summary>
    ''' <param name="X"></param>
    ''' <param name="Y"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanAttackFromField(ByVal X As Integer, ByVal Y As Integer, ByVal OpferX As Integer, ByVal OpferY As Integer) As Boolean
        If X = Me.X And Y = Me.Y Then
            Return True
        ElseIf Waffe1.ToLower <> "keine" Or MinimaleReichweite = 1 Then

            If Distance(New Point(X, Y), New Point(OpferX, OpferY)) = 1 Then
                Return True
            End If
        Else
            Dim D As Integer = Distance(New Point(X, Y), New Point(OpferX, OpferY))
            If D >= MinimaleReichweite And D <= MaximaleReichweite Then
                If Munition > 0 Then
                    Return CanIndirectMoveAndFire()
                End If
            End If
        End If
            Return False
    End Function
    Public Function IsDirectUnit() As Boolean
        If Reichweitemin = 1 Then
            If Reichweitemax = 1 Then
                Return True
            Else
                Return False
            End If
        ElseIf Waffe1 <> "Keine" Then
            Return True
        Else
            Return False
        End If
    End Function
    Public Function IsIndirectUnit() As Boolean
        If Reichweitemax > 1 Then
            If Waffe2 <> "Keine" Then
                Return True
            End If
        End If
        Return False
    End Function
    ''' <summary>
    ''' Berechnet die Reichweite unter einem bestimmten Wetter!
    ''' </summary>
    ''' <param name="Wetter"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetMaximalReichweite(ByVal Wetter As ObjektSpielfeld.Wetterarten) As Integer
        Dim RMax As Integer = MaximaleReichweite
        Dim Stelle As Integer = Array.IndexOf(Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker, Objektverwalter.Spielfeld.Regeln.Wetter)
        If Stelle >= 0 Then
        Select Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker(Stelle)
                Case ObjektSpielfeld.Wetterarten.Schnee
                    If Bewegungsart.ToLower <> "wüstenketten" Then
                        RMax -= Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                    End If
                Case ObjektSpielfeld.Wetterarten.Sandsturm
                    If Bewegungsart.ToLower <> "schneeketten" Then
                        RMax -= Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                    End If
                Case Else
                    RMax -= Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
            End Select
        End If
        Stelle = Array.IndexOf(Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker, Wetter)
        If Stelle >= 0 Then
        Select Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterartfürSenker(Stelle)
                Case ObjektSpielfeld.Wetterarten.Schnee
                    If Bewegungsart.ToLower <> "wüstenketten" Then

                        RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                    End If
                Case ObjektSpielfeld.Wetterarten.Sandsturm
                    If Bewegungsart.ToLower <> "schneeketten" Then
                        RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
                    End If
                Case Else
                    RMax += Objektverwalter.Spielfeld.AktuellerSpieler.KOS(0).WetterReichweitenbonus(Stelle)
            End Select
        End If
        Return RMax
    End Function
    ''' <summary>
    ''' Can this Indirect Unit Move and Fire afterwards?
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CanIndirectMoveAndFire() As Boolean
        If MaximaleReichweite > 1 Then
            Select Case Fähigkeit.ToLower
                Case "moveandfire", "truppenbau+moveandfire"
                    Return True
                Case Else
                    If GetSpieler.KOS(0).MoveandFire Then
                        Return True
                    End If
            End Select
        End If
    End Function
    ''' <summary>
    ''' How expansive this Unit is!
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetKosten() As Integer
        Return Koste * GetSpieler.Teurungsrate(EinheitenID, X, Y)
    End Function
#Region "Commander Wars Engine 2"
    ''' <summary>
    ''' Im neusten CoW-Modus erhalten Rang-Einheiten eine Zone die gleiche Einheiten stärkt!
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub EinheitenEffekt()
        Dim S As Integer = GetMap()
        Dim R As Integer = GetUpgradeZone()
        
        Dim L As ObjektLandschaft = Wegsuchsystem.getFeldRundrum(X, Y, S, 0, R, Nothing, Objektverwalter.Spielfeld)
        Do Until L Is Nothing
            EinheitenEffekt(L.KooX, L.KooY, S)
            L = Wegsuchsystem.getFeldRundrum(X, Y, S, 0, R, L, Objektverwalter.Spielfeld)
        Loop
    End Sub
    Private Sub EinheitenEffekt(ByVal X As Integer, ByVal Y As Integer, ByVal Schlacht As Integer)
        Dim E As ObjektEinheit = Objektverwalter.Spielfeld.Einheiten(X, Y, Schlacht)
        If E IsNot Nothing Then
            If E.Spieler = Spieler Then
                If E.EinheitenID = Me.EinheitenID Then
                    If E.TruppenStufe < TruppenStufe Then
                        UpgradeUnit(E)
                    ElseIf E.Equals(Me) Then
                        UpgradeUnit(E)
                    End If
                End If
            End If
        End If
    End Sub
    Protected Overridable Sub UpgradeUnit(ByVal E As ObjektEinheit)
        Select Case EinheitenStufe
            Case ObjektEinheit.Stufe.Leutnant
                E.ATKDEFBoost.X += 5
            Case Stufe.Offizier
                E.ATKDEFBoost.X += 10
            Case Stufe.General
                E.ATKDEFBoost.X += 10
                E.ATKDEFBoost.Y += 10
            Case Stufe.Veteran
                E.ATKDEFBoost.X += 15
                E.ATKDEFBoost.Y += 15
            Case Stufe.KO
                E.ATKDEFBoost.X += 15
                E.ATKDEFBoost.Y += 15
            Case Else
        End Select
    End Sub
    Public Function GetUpgradeZone() As Integer
        Select Case EinheitenStufe
            Case Stufe.Soldat
                Return -1
            Case Stufe.Leutnant
                Return 0
            Case Stufe.Offizier
                Return 1
            Case Stufe.General
                Return 2
            Case Else
                Return 2
        End Select
    End Function
#End Region
#End Region
#Region "Malen"
    Shared MaxTimer As Double = 0
    Public Overridable Sub Malen(ByVal X As Integer, ByVal Y As Integer, ByVal Alpha As Integer)
        If Sichtbarkeit = True And Tod = False And Leben > 0 And BildID >= 0 Then
            If My.Settings.draw3D Then
                If AnimPos >= AnimPeriode Then
                    If AnimAuszeit = 0 Then
                        'Einen neustart. Juhuu!
                        SetAnimation(AnimSetNächsterName)

                        'Der Wait-Zyklus wird ständig wiederhohlt. Allerdings mit abwechselnder zwischenwartezeit
                        If Me.AnimSetName.ToLower = "Wait".ToLower Then
                            SetFolgeAnimation("Wait", Zufallszahl(10, 30))
                        End If
                    End If
                    'wir sind am Ende angelangt.
                    If Me.AnimAuszeit >= 0 Then
                        Me.AnimAuszeit -= 1
                    End If
                End If
                ObjektLadeklasse.Einheit3D.Malen(EinheitenID, X, Y, GetMap, Spieler, Rotation, HatsichBewegt, AnimSetName, AnimPos, AnimPeriode)

                SymboleMalen(ObjektLadeklasse.Einheit3D.getPos(X, Y, EinheitenID, GetMap)) 'naja eigentlich ist die Farbe egal, aber damit es alle glücklich macht...
            Else

                'Welchen Teil des Bildes wir malen wollen
                Dim sngRotation As Double = 0
                Dim intColor As Color
                If HatsichBewegt = True Then
                    intColor = Color.FromArgb(Alpha, 150, 150, 150)
                Else
                    If Hauptmenü.Formmodus = Hauptmenü.Formmodi.Spiel Then
                        Select Case Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Gabemodus
                            Case ObjektKO.Gabemodi.Gabe
                                intColor = Color.FromArgb(Alpha, 255 - Frame * 5, 255 - Frame * 10, 255 - Frame * 15)
                            Case ObjektKO.Gabemodi.Spezialgabe
                                intColor = Color.FromArgb(Alpha, 255 - Frame * 15, 255 - Frame * 10, 255 - Frame * 5)
                            Case ObjektKO.Gabemodi.Doppelgabe
                                intColor = Color.FromArgb(Alpha, 255 - Frame * 10, 255 - Frame * 15, 255 - Frame * 5)
                            Case Else
                                intColor = Color.FromArgb(Alpha, 255, 255, 255)
                        End Select
                    Else
                        intColor = Color.FromArgb(Alpha, 255, 255, 255)
                    End If
                End If

                'prüfen ob wir aus den Screenbereich laufen

                'Festlegen welchen Bereich vom Bitmap wir kopieren

                'Welcher Teil der Textur soll gemalt werden Nichts bedeutet gesamtes Bild
                If Objektverwalter.Spielfeld.GetCommanderWarsModus = CommanderWarsGameModi.FireEmblem Then
                    Dim FireEmblemUnit As Fire_Emblem_MOD.FEUnit = Me
                    With Grafikengine.recBild
                        .X = FireEmblemUnit.UnitSize.Width * Frame : .Width = FireEmblemUnit.UnitSize.Width
                        .Y = 0 : .Height = FireEmblemUnit.UnitSize.Height
                    End With
                    'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                    'Achtung Rotationszentrum ist auch Ausgangspunkt der bemalung
                    With Grafikengine.ptfRotCenter
                        .X = FireEmblemUnit.UnitSize.Width / 2
                        .Y = FireEmblemUnit.UnitSize.Height - Hauptmenü.Feldbreite / 2
                    End With
                    Grafikengine.szfScale = FireEmblemUnit.UnitSize
                Else
                    With Grafikengine.recBild
                        .X = Hauptmenü.Feldbreite * Frame : .Width = Hauptmenü.Feldbreite
                        .Y = 0 : .Height = Hauptmenü.Feldbreite
                    End With
                    'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                    'Achtung Rotationszentrum ist auch Ausgangspunkt der bemalung
                    With Grafikengine.ptfRotCenter
                        .X = Hauptmenü.Feldbreite / 2
                        .Y = Hauptmenü.Feldbreite / 2
                    End With
                    With Grafikengine.szfScale
                        .Height = Hauptmenü.Feldbreite
                        .Width = Hauptmenü.Feldbreite
                    End With
                End If
                Grafikengine.ptfPosition = New Drawing.Point(Hauptmenü.Feldbreite * X + Objektverwalter.Spielfeld.BildschirmKooX, Hauptmenü.Feldbreite * Y + Objektverwalter.Spielfeld.BildschirmKooY)

                'Ausschnitte in den Backbuffer zeichnen
                'Wo wird das Bild gezeichnet
                '16 ist die Breite eines Feldes 8 die Hälfte das heißt wir ermitteln den Mittelpunkt des Feldes und ziehen die Hälfte der Größe der Einheit ab
                '... und wie breit ist es
            



                'jetzt wird es in den Backbuffer gezeichnet
                Dim S As ObjektSpieler = GetSpieler()
                Dim R As Integer
                Math.DivRem(S.Spieler, 2, R)
                If R = 0 Then
                    Grafikengine.szfScale.Width *= -1
                End If
                If Not S Is Nothing Then
                    If Not Hauptmenü.Formmodus = Hauptmenü.Formmodi.Editor Then
                        If S.KOS(0).SpriteVertauschung = True And S.Team <> Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                            Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(INFID).GetEinheitentextur(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                            If intColor <> Hauptmenü.NeutralFarbe Then
                                intColor = ObjektmarkiertesFeld.getMischfarbe(intColor, S.Farbe, 0.5#, False)
                            Else
                                intColor = S.Farbe
                            End If
                            Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(INFID).GetEinheitentexturMaske(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)

                        Else
                            Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(BildID).GetEinheitentextur(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                            If intColor <> Hauptmenü.NeutralFarbe Then
                                intColor = ObjektmarkiertesFeld.getMischfarbe(intColor, S.Farbe, 0.5#, False)
                            Else
                                intColor = S.Farbe
                            End If
                            Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(BildID).GetEinheitentexturMaske(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)

                        End If
                    Else
                        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(BildID).GetEinheitentextur(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                        If intColor <> Hauptmenü.NeutralFarbe Then
                            intColor = ObjektmarkiertesFeld.getMischfarbe(intColor, S.Farbe, 0.5#, False)
                        Else
                            intColor = S.Farbe
                        End If
                        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(BildID).GetEinheitentexturMaske(S.Armee), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)

                    End If
                End If

                If Objektverwalter.Spielfeld.GetCommanderWarsModus <> CommanderWarsGameModi.FireEmblem Then
                    intColor = Hauptmenü.NeutralFarbe
                    'Wir malen das Leben verloren Symbol
                    If Hauptmenü.Formmodus = Hauptmenü.Formmodi.Editor Then
                        If Leben <= 90 Then
                            Dim I As Integer = Math.DivRem(CInt(Leben), 10, 0)
                            If Leben - I * 10 > 0 Then
                                I += 1
                            End If
                            I = FindElement(Objektverwalter.Symbolfunktion, I, True)
                            With Grafikengine.ptfRotCenter
                                .X = 0
                                .Y = 0
                            End With

                            With Grafikengine.recBild
                                .X = 0 : .Width = Hauptmenü.Feldbreite / 2
                                .Y = 0 : .Height = Hauptmenü.Feldbreite / 2
                            End With
                            'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                            With Grafikengine.szfScale
                                .Height = Hauptmenü.Feldbreite / 2
                                .Width = Hauptmenü.Feldbreite / 2
                            End With
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                        End If
                        SymboleMalen(intColor)
                    Else
                        If Spieler > 0 Then
                            If Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Verstecker = False Or Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                                If Leben <= 90 Then
                                    Dim I As Integer = Math.DivRem(CInt(Leben), 10, 0)
                                    If Leben - I * 10 > 0 Then
                                        I += 1
                                    End If
                                    I = FindElement(Objektverwalter.Symbolfunktion, I, True)
                                    With Grafikengine.ptfRotCenter
                                        .X = 0
                                        .Y = 0
                                    End With

                                    With Grafikengine.recBild
                                        .X = 0 : .Width = Hauptmenü.Feldbreite / 2
                                        .Y = 0 : .Height = Hauptmenü.Feldbreite / 2
                                    End With
                                    'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                                    With Grafikengine.szfScale
                                        .Height = Hauptmenü.Feldbreite / 2
                                        .Width = Hauptmenü.Feldbreite / 2
                                    End With
                                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                                End If
                            ElseIf GetSpieler.KOS(0).IsInKOZone(X, Y) Then
                                'Wir malen das Leben
                                If Leben <= 90 Then
                                    Dim I As Integer = Math.DivRem(CInt(Leben), 10, 0)
                                    If Leben - I * 10 > 0 Then
                                        I += 1
                                    End If
                                    I = FindElement(Objektverwalter.Symbolfunktion, I, True)
                                    With Grafikengine.ptfRotCenter
                                        .X = 0
                                        .Y = 0
                                    End With

                                    With Grafikengine.recBild
                                        .X = 0 : .Width = Hauptmenü.Feldbreite / 2
                                        .Y = 0 : .Height = Hauptmenü.Feldbreite / 2
                                    End With
                                    'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                                    With Grafikengine.szfScale
                                        .Height = Hauptmenü.Feldbreite / 2
                                        .Width = Hauptmenü.Feldbreite / 2
                                    End With
                                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                                End If
                            End If
                        Else
                            Dim I As Integer = FindElement(Objektverwalter.Symbolfunktion, "Fragezeichen", True)
                            With Grafikengine.ptfRotCenter
                                .X = 0
                                .Y = 0
                            End With

                            With Grafikengine.recBild
                                .X = 0 : .Width = Hauptmenü.Feldbreite / 2
                                .Y = 0 : .Height = Hauptmenü.Feldbreite / 2
                            End With
                            'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                            With Grafikengine.szfScale
                                .Height = Hauptmenü.Feldbreite / 2
                                .Width = Hauptmenü.Feldbreite / 2
                            End With
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
                        End If
                        If Spieler >= 0 Then
                            SymboleMalen(intColor)
                        End If
                    End If
                End If
                End If
        End If
    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="Ortsvektor">3D-Symbole</param>
    ''' <remarks></remarks>
    Public Sub SymboleMalen(ByVal Ortsvektor As Vector3)
        If Tarnung Then
            'Tarnungszeichen
            Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Tarnung)
        End If
        If Besetzen Then
            'Besetzungszeichen
            Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Besetzen)
        End If
        If MunitionMax > 0 Then
            If Not HasMaterial() Then
                If Munition <= MunitionMax / 3 Then
                    'Munitionszeichen
                    Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Munition)
                End If
            End If
        End If
        If SpritMax > 0 Then
            If Treibstoff <= SpritMax / 3 Then
                'Treibstoffzeichen
                Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Treibstoff)
            End If
        End If

        'Ladungszeichen
        If Ladung.Length > 0 Then
            If Objektverwalter.Spielfeld.Regeln.Nebel > 0 Then
                If IsNothing(Ladung(0)) = False Then
                    Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
                ElseIf Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                    Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
                End If
            ElseIf Hauptmenü.Formmodus = Hauptmenü.Formmodi.Spiel Then
                If Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Verstecker = True And GetSpieler.KOS(0).IsInKOZone(X, Y) Then
                    If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                        Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
                    ElseIf IsNothing(Ladung(0)) = False Then
                        Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
                    End If
                ElseIf IsNothing(Ladung(0)) = False Then
                    Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
                End If
            ElseIf IsNothing(Ladung(0)) = False Then
                Symbol3D.Symbolmalen(Ortsvektor, Symbol3D.Zeichenarten.Ladung)
            End If
        End If
    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="intcolor">2D-Symbole</param>
    ''' <remarks></remarks>
    Public Sub SymboleMalen(ByVal intcolor As Color)
        Dim Count As Integer = 0
        If Tarnung = True Then Count += 1
        If Besetzen = True Then Count += 1
        If MunitionMax > 0 Then
            If Not HasMaterial() Then
                If Munition <= MunitionMax / 3 Then Count += 1
            End If
        End If
        If SpritMax > 0 Then
            If Treibstoff <= SpritMax / 3 Then Count += 1
        End If
        If Ladung.Length > 0 Then
            If Objektverwalter.Spielfeld.Regeln.Nebel > 0 Then
                If IsNothing(Ladung(0)) = False Then
                    Count += 1
                ElseIf Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                    Count += 1
                End If
            ElseIf Hauptmenü.Formmodus = Hauptmenü.Formmodi.Spiel Then
                If Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Verstecker = True And GetSpieler.KOS(0).IsInKOZone(X, Y) Then
                    If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                        Count += 1
                    ElseIf IsNothing(Ladung(0)) = False Then
                        Count += 1
                    End If
                ElseIf IsNothing(Ladung(0)) = False Then
                    Count += 1
                End If
            ElseIf IsNothing(Ladung(0)) = False Then
                Count += 1
            End If
        End If
        If Count > 0 Then
            'Wir ändern das Rotationszentrum zum malen
            Grafikengine.ptfRotCenter = Nothing
            With Grafikengine.recBild
                .X = 0 : .Width = Hauptmenü.Feldbreite / 2
                .Y = 0 : .Height = Hauptmenü.Feldbreite / 2
            End With
            'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
            With Grafikengine.szfScale
                .Height = Hauptmenü.Feldbreite / 2
                .Width = Hauptmenü.Feldbreite / 2
            End With
            Grafikengine.ptfPosition.X -= Hauptmenü.Feldbreite / 2
            Dim I As Integer = -1
            If Count > 1 Then
                Select Case Frame
                    Case 0
                        If Besetzen = True Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Fahnenzeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        ElseIf Ladung.Length > 0 Then
                            If Objektverwalter.Spielfeld.Regeln.Nebel > 0 Then
                                If IsNothing(Ladung(0)) = False Then
                                    I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                                ElseIf Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                                    I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichenkeineahnung", True)
                                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                                End If
                            ElseIf Hauptmenü.Formmodus = Hauptmenü.Formmodi.Spiel Then
                                If Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Verstecker = True And GetSpieler.KOS(0).IsInKOZone(X, Y) Then
                                    If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                                        I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichenkeineahnung", True)
                                        Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                                    ElseIf IsNothing(Ladung(0)) = False Then
                                        I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                                        Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                                    End If
                                ElseIf IsNothing(Ladung(0)) = False Then
                                    I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                                End If
                            ElseIf IsNothing(Ladung(0)) = False Then
                                I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                                Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                            End If
                        End If
                    Case 1
                        If Tarnung = True Or Feldtarnung = True Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Tauchzeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        End If
                    Case 2
                        If Munition <= MunitionMax / 3 Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Munitionszeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        End If
                    Case 3
                        If Treibstoff <= SpritMax / 3 Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Treibstoffzeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        End If
                End Select
            Else
                If Besetzen = True Then
                    I = FindElement(Objektverwalter.Symbolfunktion, "Fahnenzeichen", True)
                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                ElseIf Tarnung = True Or Feldtarnung = True Then
                    I = FindElement(Objektverwalter.Symbolfunktion, "Tauchzeichen", True)
                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                ElseIf Munition <= MunitionMax / 3 And Frame = 2 Then
                    If Not HasMaterial() Then
                        I = FindElement(Objektverwalter.Symbolfunktion, "Munitionszeichen", True)
                        Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                    End If
                ElseIf Treibstoff <= SpritMax / 3 And Frame = 3 Then
                    I = FindElement(Objektverwalter.Symbolfunktion, "Treibstoffzeichen", True)
                    Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                ElseIf Ladung.Length > 0 Then
                    If Objektverwalter.Spielfeld.Regeln.Nebel > 0 Then
                        If IsNothing(Ladung(0)) = False Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        ElseIf Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichenkeineahnung", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        End If
                    ElseIf Hauptmenü.Formmodus = Hauptmenü.Formmodi.Spiel Then
                        If Objektverwalter.Spielfeld.Spieler(Spieler).KOS(0).Verstecker = True And GetSpieler.KOS(0).IsInKOZone(X, Y) Then
                            If Not Objektverwalter.Spielfeld.Spieler(Spieler).Team = Objektverwalter.Spielfeld.Spieler(Objektverwalter.Spielfeld.Regeln.LetzterMensch).Team Then
                                I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichenkeineahnung", True)
                                Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                            ElseIf IsNothing(Ladung(0)) = False Then
                                I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                                Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                            End If
                        ElseIf IsNothing(Ladung(0)) = False Then
                            I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                            Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                        End If
                    ElseIf IsNothing(Ladung(0)) = False Then
                        I = FindElement(Objektverwalter.Symbolfunktion, "Transportzeichen", True)
                        Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
                    End If
                End If
            End If
        End If
        If EinheitenStufe > Stufe.Soldat Then
            If getKP() = 10 Or Frame < 2 Then
                Grafikengine.ptfRotCenter = Nothing
                Grafikengine.recBild = Nothing
                Grafikengine.szfScale = Nothing
                Grafikengine.ptfPosition = New Drawing.Point(Hauptmenü.Feldbreite * X + Objektverwalter.Spielfeld.BildschirmKooX, Hauptmenü.Feldbreite * Y + Objektverwalter.Spielfeld.BildschirmKooY)
                Dim I As Integer = FindElement(Objektverwalter.Symbolfunktion, EinheitenStufe.ToString, True)
                Grafikengine.Sprite.Draw2D(Objektverwalter.Symbole(I), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, 0, Grafikengine.ptfPosition, intcolor)
            End If
        End If
    End Sub
    Public Shared Sub Malen(ByVal X As Integer, ByVal Y As Integer, ByVal Spieler As ObjektSpieler, ByVal Frame As Integer, ByVal ID As Integer)
        ObjektEinheit.Malen(X, Y, Spieler, Frame, ID, Spieler.Farbe)
    End Sub
    Public Shared Sub Malen(ByVal X As Integer, ByVal Y As Integer, ByVal Spieler As ObjektSpieler, ByVal Frame As Integer, ByVal ID As Integer, ByVal Farbe As Color)
        Dim sngRotation As Double = 0
        Dim intColor As Color = Color.FromArgb(255, 255, 255, 255)
        If Objektverwalter.Spielfeld IsNot Nothing Then
            If Objektverwalter.Spielfeld.GetCommanderWarsModus = CommanderWarsGameModi.FireEmblem Then
                Dim FireEmblemUnit As Fire_Emblem_MOD.FEUnit = Objektverwalter.AlleEinheiten(ID).Einheit
                With Grafikengine.recBild
                    .X = FireEmblemUnit.UnitSize.Width * Frame : .Width = FireEmblemUnit.UnitSize.Width
                    .Y = 0 : .Height = FireEmblemUnit.UnitSize.Height
                End With
                'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                'Achtung Rotationszentrum ist auch Ausgangspunkt der bemalung
                With Grafikengine.ptfRotCenter
                    .X = FireEmblemUnit.UnitSize.Width / 2
                    .Y = FireEmblemUnit.UnitSize.Height - Hauptmenü.Feldbreite / 2
                End With
                With Grafikengine.szfScale
                    .Height = FireEmblemUnit.UnitSize.Height
                    .Width = FireEmblemUnit.UnitSize.Width
                End With
            Else
                With Grafikengine.recBild
                    .X = Hauptmenü.Feldbreite * Frame : .Width = Hauptmenü.Feldbreite
                    .Y = 0 : .Height = Hauptmenü.Feldbreite
                End With
                'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
                'Achtung Rotationszentrum ist auch Ausgangspunkt der bemalung
                With Grafikengine.ptfRotCenter
                    .X = Hauptmenü.Feldbreite / 2
                    .Y = Hauptmenü.Feldbreite / 2
                End With
                With Grafikengine.szfScale
                    .Height = Hauptmenü.Feldbreite
                    .Width = Hauptmenü.Feldbreite
                End With
            End If
        Else
            With Grafikengine.recBild
                .X = Hauptmenü.Feldbreite * Frame : .Width = Hauptmenü.Feldbreite
                .Y = 0 : .Height = Hauptmenü.Feldbreite
            End With
            'Falls der Zoomfaktor größer 1 ist müssen einige Ränder abgeschnitten werden
            'Achtung Rotationszentrum ist auch Ausgangspunkt der bemalung
            With Grafikengine.ptfRotCenter
                .X = Hauptmenü.Feldbreite / 2
                .Y = Hauptmenü.Feldbreite / 2
            End With
            With Grafikengine.szfScale
                .Height = Hauptmenü.Feldbreite
                .Width = Hauptmenü.Feldbreite
            End With
        End If
        Grafikengine.ptfPosition = New Drawing.Point(X, Y)

        'Ausschnitte in den Backbuffer zeichnen
        'Wo wird das Bild gezeichnet
        '16 ist die Breite eines Feldes 8 die Hälfte das heißt wir ermitteln den Mittelpunkt des Feldes und ziehen die Hälfte der Größe der Einheit ab
        '... und wie breit ist es

        Dim S As String = Spieler.Armee
        If S = "" Then
            S = Armeen.OS.ToString
        End If

        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(ID).GetEinheitentextur(S), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(ID).GetEinheitentexturMaske(S), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, Farbe)

    End Sub
    Public Shared Sub Malen(ByVal Spieler As ObjektSpieler, ByVal Frame As Integer, ByVal ID As Integer, ByVal Farbe As Color)
        Dim sngRotation As Double = 0
        Dim intColor As Color = Color.FromArgb(255, 255, 255, 255)
        Dim S As String = Spieler.Armee
        If S = "" Then
            S = Armeen.OS.ToString
        End If
        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(ID).GetEinheitentextur(S), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, intColor)
        Grafikengine.Sprite.Draw2D(Objektverwalter.AlleEinheiten(ID).GetEinheitentexturMaske(S), Grafikengine.recBild, Grafikengine.szfScale, Grafikengine.ptfRotCenter, sngRotation, Grafikengine.ptfPosition, Farbe)

    End Sub
#End Region

    ''' <summary>
    ''' Erstellt eine unabhängiges Klon
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim E As ObjektEinheit = MemberwiseClone()
        For I = 0 To Ladung.Length - 1
            If Ladung(I) IsNot Nothing Then
                E.Ladung(I) = Ladung(I).Clone
            End If
        Next
        ReDim E.GeladeneEinheitenIDs(GeladeneEinheitenIDs.Length - 1)
        For I = 0 To GeladeneEinheitenIDs.Length - 1
            E.GeladeneEinheitenIDs(I) = GeladeneEinheitenIDs(I)
        Next
        ReDim E.EntladungsUntergrund(EntladungsUntergrund.Length - 1)
        For I = 0 To EntladungsUntergrund.Length - 1
            E.EntladungsUntergrund(I) = EntladungsUntergrund(I)
        Next
        E.ATKDEFBoost = New Point(ATKDEFBoost.X, ATKDEFBoost.Y)
        Return E
    End Function

#Region "3D"
    ''' <summary>
    ''' 3D: setzt die Aktuelle Animation, je nach dem, ob sie sich schon bewegt hat, oder nicht.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub AnimationAktuallisieren()
        If HatsichBewegt Then
            'schon gezogen? na dann kann die Einheit ja in Ruhe faullenzen..
            If AnimSetName.ToLower = "Wait".ToLower Then 'Den Wait können wir ausnahmsweise abbrechen.
                SetAnimation("Idle")
                Me.AnimAuszeit = -1
            Else
                SetFolgeAnimation("Idle")
            End If
        Else
            SetFolgeAnimation("Wait") 'warte auf Befehle
        End If
    End Sub
    ''' <summary>
    ''' 3D: Lässt die Einheit eine bestimmte Animation ausführen, sollange dise aktion im .X abgespeichert ist. Ansonsten wird die erste letzte Animation abgespielt. (Ind=0)
    ''' </summary>
    ''' <param name="AnimSetName"></param>
    ''' <remarks></remarks>
    Public Sub SetAnimation(ByVal AnimSetName As String)
        ' If Me.AnimSetName.ToLower <> AnimSetName.ToLower Then
        'Wenn wir neu mit der Animation beginnen, dann am besten von vorne.
        AnimPos = 0
        ' End If
        Me.AnimSetName = AnimSetName
    End Sub
    ''' <summary>
    ''' 3D: Sobald die aktuelle Animation abgelaufen ist, wird eine andere Animation abgespielt. Es kann auch eine Versatzzeit mitgegeben werden.
    ''' </summary>
    ''' <param name="FolgeAnimName"></param>
    ''' <param name="Wartezeit">=0, wird direkt anschließend abgespielt. >0 Anz Frames wartezeit. -1=wird nie ausgeführt!</param>
    ''' <remarks></remarks>
    Public Sub SetFolgeAnimation(ByVal FolgeAnimName As String, Optional ByVal Wartezeit As Integer = 0)
        Me.AnimSetNächsterName = FolgeAnimName
        Me.AnimAuszeit = Wartezeit
    End Sub

    Public Function SetOrientation(ByVal Einheit As ObjektEinheit) As Single
        Return SetOrientation(Einheit.GetLocation)
    End Function
    Public Function SetOrientation(ByVal P As Point) As Single
        Rotation = GetOrientation(Me.GetLocation, P)
        Return Rotation
    End Function
    Public Function SetOrientation(ByVal P1 As Point, ByVal P2 As Point) As Single
        Rotation = GetOrientation(P1, P2)
        Return Rotation
    End Function
    Public Shared Function GetOrientation(ByVal P1 As Point, ByVal P2 As Point) As Single
        Dim DX As Integer = P1.X - P2.X
        Dim DY As Integer = P1.Y - P2.Y
        If DY = 0 Then
            If DX > 0 Then
                Return Math.PI * 3 / 2
            Else
                Return Math.PI / 2
            End If
        ElseIf DX = 0 Then
            If DY > 0 Then
                Return 0
            Else
                Return Math.PI
            End If
        Else
            Dim rot As Single = Math.Atan(-DX / DY)
            If DY < 0 Then 'If rot < Math.PI / 2 Or rot > Math.PI * 3 / 2 Then
                rot += Math.PI
            End If
            Return rot
        End If
    End Function
#End Region
End Class
